import 'package:flutter/material.dart';

/// Callback function for when a matrix size is selected.
typedef MatrixSizeCallback = void Function(int rows, int cols);

/// Widget for selecting matrix dimensions.
class MatrixSizeSelector extends StatefulWidget {
  /// Creates a [MatrixSizeSelector].
  const MatrixSizeSelector({
    Key? key,
    required this.onSizeSelected,
    this.maxRows = 6,
    this.maxCols = 6,
    this.cellSize = 32.0,
    this.spacing = 2.0,
  }) : super(key: key);

  /// Callback function called when a size is selected.
  final MatrixSizeCallback onSizeSelected;

  /// Maximum number of rows to display.
  final int maxRows;

  /// Maximum number of columns to display.
  final int maxCols;

  /// Size of each cell in the grid.
  final double cellSize;

  /// Spacing between cells.
  final double spacing;

  @override
  _MatrixSizeSelectorState createState() => _MatrixSizeSelectorState();
}

class _MatrixSizeSelectorState extends State<MatrixSizeSelector> {
  int? _hoveredRows;
  int? _hoveredCols;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        // color: Colors.white,
        borderRadius: BorderRadius.circular(8.0),
        // boxShadow: [
        //   BoxShadow(
        //     color: Colors.grey.withOpacity(0.1),
        //     blurRadius: 4.0,
        //     offset: const Offset(0, 2),
        //   ),
        // ],
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // Title
          Text(
            'Select Matrix Size',
            style: Theme.of(context).textTheme.titleSmall?.copyWith(color: Colors.white),
          ),
          const SizedBox(height: 8.0),
          
          // Grid
          _buildGrid(),
          
          const SizedBox(height: 8.0),
          
          // Size indicator
          Text(
            _hoveredRows != null && _hoveredCols != null
                ? '${_hoveredRows}×${_hoveredCols}'
                : 'Hover to preview',
            style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.white),
          ),
        ],
      ),
    );
  }

  Widget _buildGrid() {
    return Column(
      children: List.generate(widget.maxRows, (row) {
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: List.generate(widget.maxCols, (col) {
            return _buildCell(row + 1, col + 1);
          }),
        );
      }),
    );
  }

  Widget _buildCell(int rows, int cols) {
    final isHighlighted = _hoveredRows != null && 
                         _hoveredCols != null &&
                         rows <= _hoveredRows! && 
                         cols <= _hoveredCols!;

    return GestureDetector(
      onTap: () => widget.onSizeSelected(rows, cols),
      child: MouseRegion(
        onEnter: (_) => setState(() {
          _hoveredRows = rows;
          _hoveredCols = cols;
        }),
        onExit: (_) => setState(() {
          _hoveredRows = null;
          _hoveredCols = null;
        }),
        child: Container(
          width: widget.cellSize,
          height: widget.cellSize,
          margin: EdgeInsets.all(widget.spacing / 2),
          decoration: BoxDecoration(
            color: isHighlighted 
                ? Theme.of(context).primaryColor.withOpacity(0.3)
                : Colors.grey.withOpacity(0.1),
            border: Border.all(
              color: isHighlighted 
                  ? Theme.of(context).primaryColor
                  : Colors.grey.withOpacity(0.3),
              width: 1.0,
            ),
            borderRadius: BorderRadius.circular(2.0),
          ),
        ),
      ),
    );
  }
}

/// Dialog for selecting matrix size.
class MatrixSizeDialog extends StatelessWidget {
  /// Creates a [MatrixSizeDialog].
  const MatrixSizeDialog({
    Key? key,
    this.maxRows = 6,
    this.maxCols = 6,
  }) : super(key: key);

  /// Maximum number of rows to display.
  final int maxRows;

  /// Maximum number of columns to display.
  final int maxCols;

  /// Shows the matrix size selection dialog.
  static Future<MatrixSize?> show(
    BuildContext context, {
    int maxRows = 6,
    int maxCols = 6,
  }) {
    return showDialog<MatrixSize>(
      context: context,
      builder: (context) => MatrixSizeDialog(
        maxRows: maxRows,
        maxCols: maxCols,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Dialog(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            MatrixSizeSelector(
              maxRows: maxRows,
              maxCols: maxCols,
              onSizeSelected: (rows, cols) {
                Navigator.of(context).pop(MatrixSize(rows: rows, cols: cols));
              },
            ),
            const SizedBox(height: 16.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                TextButton(
                  onPressed: () => Navigator.of(context).pop(),
                  child: const Text('Cancel'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

/// Popup for selecting matrix size.
class MatrixSizePopup extends StatelessWidget {
  /// Creates a [MatrixSizePopup].
  const MatrixSizePopup({
    Key? key,
    required this.onSizeSelected,
    this.maxRows = 6,
    this.maxCols = 6,
  }) : super(key: key);

  /// Callback function called when a size is selected.
  final MatrixSizeCallback onSizeSelected;

  /// Maximum number of rows to display.
  final int maxRows;

  /// Maximum number of columns to display.
  final int maxCols;

  /// Shows the matrix size selection popup.
  static void show(
    BuildContext context,
    RelativeRect position, {
    required MatrixSizeCallback onSizeSelected,
    int maxRows = 6,
    int maxCols = 6,
  }) {
    showMenu<void>(
      context: context,
      position: position,
      items: [
        PopupMenuItem<void>(
          child: MatrixSizePopup(
            onSizeSelected: (rows, cols) {
              // Navigator.of(context).pop();
              onSizeSelected(rows, cols);
            },
            maxRows: maxRows,
            maxCols: maxCols,
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return MatrixSizeSelector(
      onSizeSelected: onSizeSelected,
      maxRows: maxRows,
      maxCols: maxCols,
    );
  }
}

/// A full page widget for selecting matrix size, designed to be used as a keyboard page.
class MatrixSizePage extends StatefulWidget {
  /// Creates a [MatrixSizePage].
  const MatrixSizePage({
    Key? key,
    required this.onSizeSelected,
    required this.onCancel,
    required this.switchPageButton,
    required this.goForwardButton,
    required this.goNextButton,
    required this.deleteButton,
    // required this.onSwitchPage,
    this.maxRows = 6,
    this.maxCols = 6,
  }) : super(key: key);

  /// Callback function called when a size is selected.
  final MatrixSizeCallback onSizeSelected;

  /// Callback function called when user cancels matrix creation.
  final VoidCallback onCancel;

  /// Callback function called when user switches to another page.
  // final VoidCallback onSwitchPage;
  final Widget switchPageButton;

  final Widget goForwardButton;

  final Widget goNextButton;

  final Widget deleteButton;

  /// Maximum number of rows to display.
  final int maxRows;

  /// Maximum number of columns to display.
  final int maxCols;

  @override
  State<MatrixSizePage> createState() => _MatrixSizePageState();
}

class _MatrixSizePageState extends State<MatrixSizePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // Row(
          //   mainAxisAlignment: MainAxisAlignment.spaceBetween,
          //   children: [
          //     Text(
          //       'Select Matrix Size',
          //       style: Theme.of(context).textTheme.titleMedium,
          //     ),
          //     IconButton(
          //       icon: const Icon(Icons.close),
          //       onPressed: widget.onCancel,
          //     ),
          //   ],
          // ),
          // const SizedBox(height: 16.0),
          MatrixSizeSelector(
            maxRows: widget.maxRows,
            maxCols: widget.maxCols,
            onSizeSelected: widget.onSizeSelected,
          ),
          const SizedBox(height: 16.0),
          Row(
            // mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              widget.switchPageButton,
              widget.goForwardButton,
              widget.goNextButton,
              widget.deleteButton,
              // TextButton(
              //   onPressed: widget.onCancel,
              //   child: const Text('Cancel'),
              // ),
            ],
          ),
        ],
      ),
    );
  }
}

/// Represents the selected matrix size.
class MatrixSize {
  /// Creates a [MatrixSize].
  const MatrixSize({
    required this.rows,
    required this.cols,
  });

  /// Number of rows.
  final int rows;

  /// Number of columns.
  final int cols;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is MatrixSize &&
          runtimeType == other.runtimeType &&
          rows == other.rows &&
          cols == other.cols;

  @override
  int get hashCode => rows.hashCode ^ cols.hashCode;

  @override
  String toString() => 'MatrixSize(rows: $rows, cols: $cols)';
}